package com.alb.core;

import com.alb.common.utils.PropertiesUtils;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.LinkPermission;
import java.util.Map;
import java.util.Properties;

/**
 * 网关配置加载器
 *
 * @author MattS
 * @date 2024/04/25
 */
@Slf4j
public class ConfigLoader {
    private static final String CONFIG_FILE = "gateway.properties";
    private static final String ENV_PREFIX = "GATEWAY_";
    private static final String JVM_PREFIX = "gateway.";

    //使用单例的设计模式
    private static final ConfigLoader INSTANCE = new ConfigLoader();

    private ConfigLoader() {
    }

    ;

    public static ConfigLoader getInstance() {
        return INSTANCE;
    }

    private Config config;

    /**
     * 获取配置
     *
     * @return {@link Config}
     */
    public static Config getConfig() {
        return INSTANCE.config;
    }

    /**
     * 运行参数>JVM参数>环境变量>配置文件>默认值
     * 核心加载过程
     *
     * @return {@link Config}
     */
    public Config load(String args[]) {
        //配置对象默认值
        config = new Config();
        //从配置文件加载配置
        loadFromConfigFile();
        //从环境变量加载配置
        loadFromEnv();
        //从JVM参数加载配置
        loadFromJvm();
        //从运行参数加载配置
        loadFromArgs(args);

        return config;
    }

    /**
     *从运行参数中获取配置
     */
    private void loadFromArgs(String []args) {
        if (args != null & args.length > 0) {
            Properties properties = new Properties();
            for (String arg : args) {
                if (arg.startsWith("--") && arg.contains("=")) {
                    properties.put(arg.substring(2, arg.indexOf("=")),
                            arg.substring(arg.indexOf("=") + 1));
                }
            }
            PropertiesUtils.properties2Object(properties, config);
        }
    }

    /**
     *从JVM中获取配置
     */
    private void loadFromJvm() {
        Properties properties = System.getProperties();
        PropertiesUtils.properties2Object(properties,config,JVM_PREFIX);
    }

    /**
     * 从环境变量中加载配置
     */
    private void loadFromEnv() {
        Map<String, String> env = System.getenv();
        Properties properties = new Properties();
        properties.putAll(env);
        PropertiesUtils.properties2Object(properties,config);
    }

    /**
     * 从配置文件中加载配置
     *
     * @return {@link Config}
     */
    private void loadFromConfigFile() {
        //从默认指定路径的文件中加载配置
        InputStream inputStream = ConfigLoader.class.getClassLoader().getResourceAsStream(CONFIG_FILE);
        if (inputStream != null) {
            Properties properties = new Properties();
            try {
                properties.load(inputStream);
                PropertiesUtils.properties2Object(properties, config);
            } catch (IOException e) {
                log.warn("load config file error", CONFIG_FILE, e);
            } finally {
                if (inputStream != null) {
                    try {
                        inputStream.close();
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
    }

}
